# encoding: utf-8
"""
数据库信息
"""

import platform
import os
import configparser
from typing import Dict, Set, Tuple

import psycopg2
import pandas as pd

from . import POSTGRESQL_INFO_

# 日志地址
DB_BASE_PATH = r'D:/config/contract' if platform.system() == 'Windows' else r'/app/contract/config/schedule'
DB_BASE = DB_BASE_PATH + r'//db.ini'

if os.path.exists(DB_BASE):
    config = configparser.ConfigParser()
    config.read(DB_BASE)
    name = 'db'
    POSTGRESQL_INFO = {
    'database': config.get(name, 'database'),
    'user': config.get(name, 'user'),
    'password': config.get(name, 'password'),
    'host': config.get(name, 'host'),
    'port': config.get(name, 'port')
    }
else:
    POSTGRESQL_INFO = POSTGRESQL_INFO_


'''
创建基础信息表
'''

create_init_sql = '''
CREATE TABLE if NOT EXISTS "public"."init_model_param" (
  "id" varchar(128) COLLATE "pg_catalog"."default" NOT NULL,
  "default_model_id" varchar(255) COLLATE "pg_catalog"."default",
  "task_name" varchar(255) COLLATE "pg_catalog"."default",
  "model_status" varchar(255) COLLATE "pg_catalog"."default",
  "update_time" timestamp(0),
  CONSTRAINT "init_model_param_pkey" PRIMARY KEY ("id")
)
;
'''

create_model_servers_sql = '''
CREATE TABLE if NOT EXISTS "public"."model_servers" (
  "server_id" varchar(256) COLLATE "pg_catalog"."default" NOT NULL,
  "default_model_id" varchar(256) COLLATE "pg_catalog"."default",
  "now_model_id" varchar(256) COLLATE "pg_catalog"."default",
  "pid" varchar(256) COLLATE "pg_catalog"."default",
  "create_time" timestamp(6),
  "update_time" timestamp(6),
  "heartbeat_time" timestamp(6),
  "load_model_label" int2,
  "load_model_error" text COLLATE "pg_catalog"."default",
  CONSTRAINT "model_servers_pkey" PRIMARY KEY ("server_id")
);
COMMENT ON COLUMN "public"."model_servers"."load_model_label" IS '1表示正常，2表示错误';
'''


def create_init_model_table():
    """
    创建基本信息表
    :return:
    """
    # 创建表
    cnx = psycopg2.connect(**POSTGRESQL_INFO)
    cur = cnx.cursor()

    cur.execute(create_init_sql)
    cur.execute(create_model_servers_sql)
    cnx.commit()


create_init_model_table()

'''
获取基础信息
'''


def get_init_params():
    cnx = psycopg2.connect(**POSTGRESQL_INFO)
    cur = cnx.cursor()
    query = "select default_model_id from public.init_model_param where id = '0' "
    cur.execute(query)
    data = cur.fetchall()
    if len(data) == 0:
        query_insert = "insert into init_model_param(id, default_model_id, model_status) values ('0', '0', 'FREE')"
        cur.execute(query_insert)
        cnx.commit()
        default_model_id = '0'
    else:
        default_model_id = data[0][0]
    init_params = {
        'default_model_id': default_model_id
    }
    return init_params


def get_ignore_error_phrases() -> Tuple[Dict[str, Set], Dict[str, Set]]:
    cnx = psycopg2.connect(**POSTGRESQL_INFO)
    data = pd.read_sql('select * from df_ignore_review_error_char', cnx)
    total_ignore_phrases = {}
    total_correct_ignore_phrases = {}
    for index, row in data.iterrows():
        # 特殊字符串不处理
        target_error_char = str(row['origin_str'])
        # 修正的字符串
        correction_str = str(row['correction_str'])
        try:
            total_ignore_phrases.setdefault(target_error_char, set())
        except:
            continue
        # 最长的字符串
        location_str_long: str = row['location_str_long']
        # 最短的字符串
        location_str_short = row['location_str_short']
        '''
        此处逻辑有问题, 理论上直接使用location_str_short,然而后端存数据的时候这个值有错误, 所以使用location_str_shot修正
        '''
        # 获取左右的关键词
        check_ignore_phrase = location_str_short if len(location_str_short) >= 3 else None
        if check_ignore_phrase is None:
            # 从长字符串中获取
            target_index = location_str_long.find(target_error_char)
            if target_index != -1:
                # 获取区间
                target_interval = [max(target_index - 1, 0), min(target_index + len(target_error_char) + 1, len(location_str_long))]
                check_ignore_phrase = location_str_long[target_interval[0]: target_interval[1]]
        # 添加错误标识
        if check_ignore_phrase is not None and len(check_ignore_phrase) in [2, 3]:
            total_ignore_phrases[target_error_char].add(check_ignore_phrase)

        # 添加标识错误忽略
        correct_ignore_key = target_error_char + '_' + correction_str
        try:
            total_correct_ignore_phrases.setdefault(correct_ignore_key, set())
        except:
            continue
        total_correct_ignore_phrases[correct_ignore_key].add(check_ignore_phrase)
    return total_ignore_phrases, total_correct_ignore_phrases

